package com.nstc.sftpExchange.config.sftp;

import cn.hutool.core.collection.CollectionUtil;
import com.jcraft.jsch.SftpATTRS;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.pool2.PooledObject;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

@Slf4j
public class SftpConnValidator {
    private final ExecutorService executorService = Executors.newCachedThreadPool();
    private static final long TIME_OUT_ONE_MINUTE = 60000L;

    public boolean valid(PooledObject<FtpConnection> p, long timeoutInMillion) {
        boolean result = false;
        List<Callable<Boolean>> validTaskList = getCallables(p);
        List<Future<Boolean>> futures;
        try {
            futures = executorService.invokeAll(validTaskList, timeoutInMillion <= 0 ? TIME_OUT_ONE_MINUTE : timeoutInMillion, TimeUnit.MILLISECONDS);
            if (CollectionUtil.isNotEmpty(futures)) {
                Future<Boolean> future = futures.get(0);
                if (future.isCancelled()) {
                    result = false;
                } else {
                    if (future.isDone()) {
                        result = future.get();
                    }
                }
            }
        } catch (Exception e) {
            log.error("invokeAll error", e);
        }
        return result;
    }

    private static List<Callable<Boolean>> getCallables(PooledObject<FtpConnection> p) {
        List<Callable<Boolean>> validTaskList = new ArrayList<>();
        validTaskList.add(() -> {
            boolean valid;
            String homeDir = p.getObject().getHomeDir();
            if (StringUtils.isNotEmpty(homeDir)) {
                try {
                    SftpATTRS attrs = p.getObject().getSftpClient().getClient().stat(homeDir);
                    valid = true;
                } catch (Exception e) {
                    valid = false;
                    log.error("validate failed", e);
                }
            } else {
                valid = p.getObject().getSftpClient().getClient().isConnected();
            }
            return valid;
        });
        return validTaskList;
    }
}